package com.example.demo.utils;

/**
 * @description : 密码安全策略，杜绝弱口令
 * @author      : SXY
 * @date        : 2020-04-16上午17:16:50
 * @version     : 1.0
 * 引用自  https://blog.csdn.net/qq_41056064/article/details/105652451
*/

public class CheckPwdUtils {

        /**
         * @brief   检测密码中字符长度
         * @param[in] password            密码字符串
         * @return  符合长度要求 返回true
         */
        public static boolean checkPasswordLength(String password) {
            boolean flag =false;

            if("".equals(PwdSecurityConfig.MAX_LENGTH)) {
                if (password.length() >= Integer.parseInt(PwdSecurityConfig.MIN_LENGTH)) {
                    flag = true;
                }
            }else{
                if (password.length() >= Integer.parseInt(PwdSecurityConfig.MIN_LENGTH) &&
                        password.length() <= Integer.parseInt(PwdSecurityConfig.MAX_LENGTH)) {
                    flag = true;
                }
            }
            return flag;
        }

        /**
         * @brief   检测密码中是否包含数字
         * @param[in] password            密码字符串
         * @return  包含数字 返回true
         */
        public static boolean checkContainDigit(String password) {
            char[] chPass = password.toCharArray();
            boolean flag = false;
            int num_count = 0;

            for (int i = 0; i < chPass.length; i++) {
                if (Character.isDigit(chPass[i])) {
                    num_count++;
                }
            }

            if (num_count >= 1){
                flag = true;
            }
            return flag;
        }

        /**
         * @brief   检测密码中是否包含字母（不区分大小写）
         * @param[in] password            密码字符串
         * @return  包含字母 返回true
         */
        public static boolean checkContainCase(String password) {
            char[] chPass = password.toCharArray();
            boolean flag = false;
            int char_count = 0;

            for (int i = 0; i < chPass.length; i++) {
                if (Character.isLetter(chPass[i])) {
                    char_count++;
                }
            }

            if (char_count >= 1) {
                flag = true;
            }
            return flag;
        }

        /**
         * @brief   检测密码中是否包含小写字母
         * @param[in] password            密码字符串
         * @return  包含小写字母 返回true
         */
        public static boolean checkContainLowerCase(String password) {
            char[] chPass = password.toCharArray();
            boolean flag = false;
            int char_count = 0;

            for (int i = 0; i < chPass.length; i++) {
                if (Character.isLowerCase(chPass[i])) {
                    char_count++;
                }
            }

            if (char_count >= 1) {
                flag = true;
            }
            return flag;
        }

        /**
         * @brief   检测密码中是否包含大写字母
         * @param[in] password            密码字符串
         * @return  包含大写字母 返回true
         */
        public static boolean checkContainUpperCase(String password) {
            char[] chPass = password.toCharArray();
            boolean flag = false;
            int char_count = 0;

            for (int i = 0; i < chPass.length; i++) {
                if (Character.isUpperCase(chPass[i])) {
                    char_count++;
                }
            }

            if (char_count >= 1) {
                flag = true;
            }
            return flag;
        }

        /**
         * @brief   检测密码中是否包含特殊符号
         * @param[in] password            密码字符串
         * @return  包含特殊符号 返回true
         */
        public static boolean checkContainSpecialChar(String password) {
            char[] chPass = password.toCharArray();
            boolean flag = false;
            int special_count = 0;

            for (int i = 0; i < chPass.length; i++) {
                if (PwdSecurityConfig.SPECIAL_CHAR.indexOf(chPass[i]) != -1) {
                    special_count++;
                }
            }

            if (special_count >= 1){
                flag = true;
            }
            return flag;
        }




        /**
         * @brief   评估a-z,z-a这样的连续字符
         * @param[in] password            密码字符串
         * @return  含有a-z,z-a连续字符串 返回true
         */
        public static boolean checkSequentialChars(String password) {
            String t_password = new String(password);
            boolean flag = false;
            int limit_num = Integer.parseInt(PwdSecurityConfig.LIMIT_LOGIC_NUM_CHAR);
            int normal_count = 0;
            int reversed_count = 0;

            //检测包含字母(区分大小写)
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_DISTINGGUISH_CASE)) {

            }else{
                t_password = t_password.toLowerCase();
            }
            int n = t_password.length();
            char[] pwdCharArr = t_password.toCharArray();

            for (int i=0; i+limit_num<=n; i++) {
                normal_count = 0;
                reversed_count = 0;
                for (int j=0; j<limit_num-1; j++) {
                    if (pwdCharArr[i+j+1]-pwdCharArr[i+j]==1) {
                        normal_count++;
                        if(normal_count == limit_num -1){
                            return true;
                        }
                    }

                    if (pwdCharArr[i+j]-pwdCharArr[i+j+1]==1) {
                        reversed_count++;
                        if(reversed_count == limit_num -1){
                            return true;
                        }
                    }
                }
            }
            return flag;
        }

        /**
         * @brief   评估aaaa,1111这样的相同连续字符
         * @param[in] password            密码字符串
         * @return  含有aaaa,1111等连续字符串 返回true
         */
        public static boolean checkSequentialSameChars(String password) {
            String t_password = new String(password);
            int n = t_password.length();
            char[] pwdCharArr = t_password.toCharArray();
            boolean flag = false;
            int limit_num = Integer.parseInt(PwdSecurityConfig.LIMIT_NUM_SAME_CHAR);
            int count = 0;
            for (int i=0; i+limit_num<=n; i++) {
                count=0;
                for (int j=0; j<limit_num-1; j++) {
                    if(pwdCharArr[i+j] == pwdCharArr[i+j+1]) {
                        count++;
                        if (count == limit_num -1){
                            return true;
                        }
                    }
                }
            }
            return flag;
        }

        /**
         * @brief   评估密码中包含的字符类型是否符合要求
         * @param[in] password            密码字符串
         * @return  符合要求 返回true
         */
        public static boolean EvalPWD(String password) {
            if (password == null || "".equals(password)) {
                return false;
            }
            boolean flag = false;

            /**
             * 检测长度
             */
            String checkPasswordLength = PwdSecurityConfig.CHECK_PASSWORD_LENGTH;
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_PASSWORD_LENGTH)){
                flag = checkPasswordLength(password);
                if (!flag) {
                    return false;
                }
            }
            /**
             * 大小写，数字，特殊符号，满足其中三种即可
             */
            int i = 0;
            /**
             * 检测包含数字
             */
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_CONTAIN_DIGIT)){
                flag = checkContainDigit(password);
                if (flag) {
                    i++;
                }
            }
            /**
             * 检测包含字母(区分大小写)
             */
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_DISTINGGUISH_CASE)){
                //检测包含小写字母
                if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_LOWER_CASE)){
                    flag = checkContainLowerCase(password);
                    if (flag) {
                        i++;
                    }
                }

                //检测包含大写字母
                if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_UPPER_CASE)){
                    flag = checkContainUpperCase(password);
                    if (flag) {
                        i++;
                    }
                }
            }else {
                flag = checkContainCase(password);
                if (!flag) {
                    return false;
                }
            }

            /**
             * 检测包含特殊符号
             */
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_CONTAIN_SPECIAL_CHAR)){
                flag = checkContainSpecialChar(password);
                if (flag) {
                    i++;
                }
            }
            if(i<3){
                return false;
            }


            /**
             * 检测逻辑位置连续
             */
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_LOGIC_SEQUENTIAL)){
                flag = checkSequentialChars(password);
                if (flag) {
                    return false;
                }
            }

            /**
             * 检测相邻字符是否相同
             */
            if (PwdSecurityConfig.ENABLE.equals(PwdSecurityConfig.CHECK_SEQUENTIAL_CHAR_SAME)){
                flag = checkSequentialSameChars(password);
                if (flag) {
                    return false;
                }
            }
            return true;
        }






}
